#pragma once
#include <dialects/CFG/Dialect.h>
#include <lcir/IR/ExprTemps.h>
#include <lcir/IR/Type.h>
#include <lcir/IR/Slots.h>
#include <queue>
#include <vector>
namespace lcir::cfg {
class BlockTy : public BasicTypeCRTP<BlockTy, CFGDialect> {
 public:
  BlockTy() : BasicTypeCRTP("CondBlock") {}
};

class BlockProto : public PrototypeCRTP<BlockProto, CFGDialect, LambdaRef>{
  std::vector<BlockProto*> prevs;
  std::vector<BlockProto*> succs;
 public:
 	BlockProto(Lambda *lambda) : PrototypeCRTP("CondBlock", BlockTy::get()) {
    getSlot<LambdaRef>()->setLambda(lambda);
  }
  Lambda *getLambda() { return getSlot<LambdaRef>()->getLambda(); }
  void addPrever(BlockProto *prever) {
    prevs.push_back(prever);
  }
  void addSuccessor(BlockProto *success) {
    succs.push_back(success);
  }
  /**
   * @brief 判断该Block是否密封（最后一个Op为终结Op）
   */
  bool isSealed() {
    return getLambda()->getExprs().back()->hasTemp<Terminator>();
  }

  // 返回prevs
  std::vector<BlockProto*> getPrevs() { return prevs; }
  // 返回succs
  std::vector<BlockProto*> getSuccs() { return succs; }
};

inline void setBlockEdge(BlockProto *source, BlockProto *target) {
  source->addSuccessor(target);
  target->addPrever(source);
}


}  // namespace lcir::CFG